# -*- coding: utf-8 -*-
import shapefile
from shapely.geometry import Point, asPolygon

import sys
reload(sys)
sys.setdefaultencoding('utf8')

import json
import urllib2
import time
from functools import wraps
def retry(ExceptionToCheck, tries=4, delay=1, backoff=2, logger=None):
    def deco_retry(f):

        @wraps(f)
        def f_retry(*args, **kwargs):
            mtries, mdelay = tries, delay
            while mtries > 1:
                try:
                    return f(*args, **kwargs)
                except ExceptionToCheck, e:
                    msg = "%s, Retrying in %d seconds..." % (str(e), mdelay)
                    if logger:
                        logger.warning(msg)
                    else:
                        print 'WARNING', msg
                    time.sleep(mdelay)
                    mtries -= 1
                    mdelay *= backoff
            return f(*args, **kwargs)

        return f_retry

    return deco_retry

access_token="1MNrcRmU3mZgCuKgHukfIt9XF2GblvcC"
access_token_gd="2b7de0dc015fe07cbc4125947b8f7c04"


@retry(Exception)
def request(uri, **kvargs):
    # if 'ak' not in kvargs: kvargs['ak'] = access_token
    url = '{}{}{}'.format(uri,
                          '&' if '?' in uri else '?',
                          '&'.join('{}={}'.format(k, kvargs[k]) for k in kvargs))
    content = urllib2.urlopen(url).read()
    result = json.loads(content)
    if result['status'] == kvargs['rescode']:
        return result[kvargs['resdata']]
    else:
        raise urllib2.URLError(result['status'])

def geocoding(address,apitype):
    uri_base = "http://api.map.baidu.com/geocoding/v3/"
    url_gd = 'https://restapi.amap.com/v3/geocode/geo'
    if(apitype=='gd'):
        return request(url_gd, address=address, output='json',key=access_token_gd,rescode=u'1',resdata='geocodes')
    else:
        return request(uri_base, address=address, output='json',ak=access_token,rescode=0,resdata='result')

def LoadRecords(datasource):
    records = []
    with shapefile.Reader(datasource) as shpfile:
        for data in shpfile.iterShapeRecords():
            record = data.record.as_dict()
            record['shape'] = asPolygon(data.shape.points)
            records.append(record)
    return records

def GetLocation(records, longitude, latitude, fields):
    position = Point(longitude, latitude)
    for record in records:
        # print record['shape']
        if not record['shape'].contains(position): continue
        return {field:record[field] for field in fields}
    
def transcode(result, records, fields,apitype):
    print json.dumps(result,ensure_ascii=False)
    if(apitype == 'gd'):
        location = result[0]['location']
        result[0]['coding'] = GetLocation(records, float(location.split(',')[0]),float(location.split(',')[1]), fields)
        return result[0]
    else:
        location = result['location']
        result['coding'] = GetLocation(records, location['lng'], location['lat'], fields)
        return result

class Transcoder():
    def __init__(self, datasource):
        self.records = LoadRecords(datasource)

    def trans(self, address, apitype='bd'):
        res = geocoding(address,apitype)
        return transcode(res, self.records, self.fields,apitype)

    def getfields(self):
        if self.records.count > 0:
            return self.records[0].keys()
        else:
            return []

    def codes(self):
        return [tuple(record[field] for field in self.fields) for record in self.records]

    def setFields(self,fields):
        self.fields = fields
if __name__ == '__main__':
    datasource =  ur'D:\\desktop\\第七次人口普查\\滨州地址比对\\371625002_gd.shp'
    #print LoadRecords(datasource)
    coder = Transcoder(datasource)
    coder.setFields( ['AREA_CODE', 'NAME'])
    print coder.trans(u'山东省泰安市泰山区泰山大街566号')
    # print coder.codes()
